define(function () {
    /**
     * 原生js纯功能的实现
     * 把所有模块集合起来放到对象tl里面
     * @namespace 基础工具库
     */
    var tl = (function () {
        /**
         * @description 按照指定参数去除空格
         * @function
         * @param {String}  str 要处理的字符串
         * @param {String}  conditions 去除空格的位置
         * @return {String} 按照指定格式去除掉空格后的字符串
         */
        var trim = function (str, conditions) {
            switch (conditions) {
                //去除左侧空格
                case "left":
                    return str.replace(/^\s*/g, "");
                //去除右侧空格
                case "right":
                    return str.replace(/\s*$/g, "");
                //去除两边空格
                case "both":
                    return str.replace(/(^\s*)|(\s*$)/g, "");
                //去除所有空格
                case "all":
                    return str.replace(/\s/g, "");
                //默认去除所有空格
                default:
                    return str.replace(/\s/g, "");
            }
        };

        /**
         * @description 判断是否是数组
         * @function
         * @param {Object}  obj 要判断的对象
         * @return {Boolean} 返回是否为数组的boolean类型
         */
        var isArray = function (obj) {
            return Object.prototype.toString.call(obj) === '[object Array]';
        };

        /**
         * @description 判断是否是function
         * @function
         * @param {Object}  obj 要判断的对象
         * @return {Boolean} 返回是否为函数的boolean类型
         */
        var isFunc = function(obj) {
            return Object.prototype.toString.call(obj) === '[object Function]';
        };

        /**
         * @description 判断是否是微信浏览器
         * @function
         * @return {Boolean} 返回是否为微信浏览器的boolean类型
         */
        var isWechat = function () {
            var bWechat = false;
            var ua = navigator.userAgent.toLowerCase();
            if (ua.match(/MicroMessenger/i) == "micromessenger") {
                bWechat = true;
            }
            return bWechat;
        };

        /**
         * @description 检查数据是否合法
         * @function
         * @param {Json}  {value:"",msg:"",reg:"",func:function(){}} 要判断的对象
         * @return {Boolean}
         */
        var checkValue = function (option) {
            var re = option.reg;
            if (re.test(option.value)) {
                if (option.msg && option.msg != "") {
                    if (option.func && typeof option.func == "function") {
                        option.func.call(this, option.msg);
                    }
                }
                return true;
            }
            return false;
        };

        /**
         * @description 保留小数,默认将值处理成固定两位小数。如果传入指定保留小数位数，则按指定数处理。若为整数，则补0。
         * @function
         * @param {Number}  numb 要处理的小数
         * @param {Number}  n 指定保留小数的位数
         * @return {String} 返回指定位数的小数
         */
        var fixedDecimal = function (numb, n) {
            n = n || 2;
            numb = numb + "";
            var intPart, decimalPart;
            if (numb.indexOf(".") > -1) {
                intPart = numb.split(".")[0];
                decimalPart = numb.split(".")[1];
                if (decimalPart.length > n) {
                    numb = intPart + "." + decimalPart.substring(0, n);
                } else if (decimalPart.length == n) {
                    numb = intPart + "." + decimalPart;
                } else if (decimalPart.length < n) {
                    numb = intPart + "." + decimalPart;
                    for (var i = decimalPart.length; i < n; i++) {
                        numb += "0";
                    }
                }
            } else {
                numb = numb + ".";
                for (var j = 0; j < n; j++) {
                    numb += "0";
                }
            }
            return numb;
        };

        /**
         * @description 不足指定位数，在该数前面填满0
         * @function
         * @param {String}  val 要处理的字符串
         * @param {Number}  n 指定长度
         * @return {String} 返回按指定长度补足0的字符串
         */
        var fillZero = function (val, n) {
            var len = val.toString().length;
            while (len < n) {
                val = "0" + val;
                len++;
            }
            return val;
        };

        /**
         * @description 获取url中的参数，若指定key，则仅返回key对应的值
         * @function
         * @param {String}  key 要获取的key
         * @return {Object} 根据key返回对应的值
         */
        var getUrlParam = function (key) {
            var paramStr = decodeURI(window.location.search.substring(1));
            var option = null;
            if (paramStr.length > 0) {
                var params = paramStr.split("&");
                option = {};
                for (var i = 0; i < params.length; i++) {
                    option[params[i].split("=")[0]] = params[i].split("=")[1];
                }
                if (key) {
                    return option[key] || null;
                }
            }
            return option;
        };

        /**
         * @description 根据指定时间倒计时
         * @function
         * @param {Date}  endTime 指定结束时间
         * @return {Object} {day:"天",hour:"时",minute:"分",second:"秒",Ms:"毫秒"}包含天、时、分、秒、毫秒的对象
         */
        var countdown = function (endTime) {
            var countdowns = {};
            var nowTime = (new Date()).getTime();//当前时间
            var time = endTime.getTime() - nowTime;
            countdowns.day = Math.floor(time / (1000 * 60 * 60 * 24));
            countdowns.hour = Math.floor(time / (1000 * 60 * 60)) % 24;
            countdowns.minute = Math.floor(time / (1000 * 60)) % 60;
            countdowns.second = Math.floor(time / 1000) % 60;
            countdowns.Ms = Math.floor(time / 100) % 10;
            return countdowns;
        };

        /**
         * @description 校验输入值，去除非数字
         * @function
         * @param {String}  value 要处理的字符串
         * @return {String} 返回去除非数字的字符串
         */
        var fixedNumber = function (value) {
            value = value.replace(/\D+/g, "");
            return value;
        };

        /**
         * @description 根据ID判断元素是否存在
         * @function
         * @param {String}  id 要判断元素的id
         * @return {Boolean} 返回要判断的元素是否存在
         */
        var isDom = function (id) {
            if (document.getElementById(id)) {
                return true;
            }
            return false;
        };

        /**
         * @description 返回浏览器可视区域的位置
         * @function
         * @return {Json} {left:"",top:"",width:"",height:""}返回浏览器可视区域的滚动位置，及宽高
         */
        var getClient = function () {
            var l, t, w, h;
            l = document.documentElement.scrollLeft || document.body.scrollLeft;
            t = document.documentElement.scrollTop || document.body.scrollTop;
            w = document.documentElement.clientWidth;
            h = document.documentElement.clientHeight;
            return { left: l, top: t, width: w, height: h };
        };


        /**
         * @description 返回待加载元素位置
         * @function
         * @param {Object} el 待加载元素对象
         * @return {Json} {left:"",top:"",width:"",height:""}返回待加载元素的绝对位置，和宽高
         */
        var getSubClient = function (el) {
            var l = 0, t = 0, w, h;
            w = el.offsetWidth;
            h = el.offsetHeight;
            while (el.offsetParent) {
                l += el.offsetLeft;
                t += el.offsetTop;
                el = el.offsetParent;
            }
            return { left: l, top: t, width: w, height: h };
        };

        /**
         * @description 判断两个矩形是否相交,返回一个布尔值
         * @function
         * @param {Object} rec1 浏览器可视区域的滚动位置，及宽高
         * @param {Object} rec2 待加载元素的绝对位置，和宽高
         * @return {Boolean} 返回待加载元素是否在可视区域内
         */
        var bIntersect = function (rec1, rec2) {
            var lc1, lc2, tc1, tc2, w1, h1;
            lc1 = rec1.left + rec1.width / 2;
            lc2 = rec2.left + rec2.width / 2;
            tc1 = rec1.top + rec1.height / 2;
            tc2 = rec2.top + rec2.height / 2;
            w1 = (rec1.width + rec2.width) / 2;
            h1 = (rec1.height + rec2.height) / 2;
            return Math.abs(lc1 - lc2) < w1 && Math.abs(tc1 - tc2) < h1;
        };

        /**
         * @description 判断指定元素是否拥有某个样式
         * @function
         * @param {Object} elements 指定元素
         * @param {String} cName 样式名
         * @return {Boolean} 返回指定元素是否引用指定样式名
         */
        var hasClass = function (elements, cName) {
            return !!elements.className.match(new RegExp("(\\s|^)" + cName + "(\\s|$)"));
        };

        /**
         * @description 给指定元素添加样式
         * @function
         * @param {Object} elements 指定元素
         * @param {String} cName 样式名
         */
        var addClass = function (elements, cName) {
            if (!hasClass(elements, cName)) {
                elements.className += " " + cName;
            }
        };

        /**
         * @description 移除指定元素的样式
         * @function
         * @param {Object} elements 指定元素
         * @param {String} cName 样式名
         */
        var removeClass = function (elements, cName) {
            if (hasClass(elements, cName)) {
                elements.className = elements.className.replace(new RegExp("(\\s|^)" + cName + "(\\s|$)"), " ");
            }
        };

        /**
         * @description 更新HTML5离线存储缓存
         * @function
         */
        var updateCache = function () {
            if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
                window.applicationCache.update();
            }
        };

        /**
         * @description 克隆对象，深度copy
         * @function
         * @param {Object} obj 原对象
         * @return {Object} 返回克隆后的对象
         */
        var clone = function(obj) {
            var result = {};
            for (var key in obj) {
                result[key] = typeof obj[key] === 'object' ? clone(obj[key]) : obj[key];
            }
            return result;
        };

        /**
         * 根据样式名返回拥有该样式的所有元素
         * @param cName --样式名
         * @returns {Array} --返回所有拥有指定样式名的元素对象数组
         */
        var getCNameEles = function (cName) {
            var arr = [];
            //获取到页面中所有的DOM元素
            var tags = document.getElementsByTagName("*");
            //循环得到每一个dom元素，保存到数组arr里
            for (var i = 0, len = tags.length; i < len; i++) {
                if (tags[i].getAttribute("class") && tags[i].getAttribute("class").indexOf(cName) > -1) {
                    arr.push(tags[i]);
                }
            }
            return arr;
        };

        /**
         * @description 获取元素在页面中的绝对位置
         * @function
         * @param {Object} el 当前元素
         * @return {Object} 返回当前元素在页面中的绝对位置
         */
        var offset = function(el) {
            var left = -el.offsetLeft;
            var top = -el.offsetTop;

            while (el == el.offsetParent) {
                left -= el.offsetLeft;
                top -= el.offsetTop;
            }

            return {
                left: left,
                top: top
            };
        };

        var goUrl = function(opts){
            var param='';
            var href = window.location.href;
            var url = href.substring(0,href.indexOf('?'));
            for(var name in opts) {
                param += name + '=' + opts[name] + '&';
            }
            url += '?' + param;
            url = url.substring(0, url.length - 1);
            window.location.href = url;
        }
        // 加法
        function accAdd(a, b) {
            var c, d, e;
            try {
                c = a.toString().split(".")[1].length;
            } catch (f) {
                c = 0;
            }
            try {
                d = b.toString().split(".")[1].length;
            } catch (f) {
                d = 0;
            }
            return e = Math.pow(10, Math.max(c, d)), (accMul(a, e) + accMul(b, e)) / e;
        }
        // 减法
        function accSub(a, b) {
            var c, d, e;
            try {
                c = a.toString().split(".")[1].length;
            } catch (f) {
                c = 0;
            }
            try {
                d = b.toString().split(".")[1].length;
            } catch (f) {
                d = 0;
            }
            return e = Math.pow(10, Math.max(c, d)), (accMul(a, e) - accMul(b, e)) / e;
        }
        // 乘法
        function accMul(a, b) {
            var c = 0,
                d = a.toString(),
                e = b.toString();
            try {
                c += d.split(".")[1].length;
            } catch (f) { }
            try {
                c += e.split(".")[1].length;
            } catch (f) { }
            return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
        }

        // 除法
        function accDiv(a, b) {
            var c, d, e = 0,
                f = 0;
            try {
                e = a.toString().split(".")[1].length;
            } catch (g) { }
            try {
                f = b.toString().split(".")[1].length;
            } catch (g) { }
            return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), accMul(c / d, Math.pow(10, f - e));
        }

        return {
            isWechat: isWechat,//判断是否是微信浏览器 line-40
            trim: trim,//按照指定参数去除空格
            isArray: isArray,//判断是否是数组
            isFunction: isFunc,//判断是否是function
            checkValue: checkValue,//检查数据是否合法
            fixedDecimal: fixedDecimal,//将值处理成2位小数 line_29
            fillZero: fillZero,//不足指定位数，在该数前面填满0 line_30
            getUrlParam: getUrlParam,//获取url中的参数 line-27
            countdown: countdown,//根据指定时间倒计时 line_57
            fixedNumber: fixedNumber,//校验输入值，去除非数字 line-17
            idDom: isDom,//根据ID判断元素是否存在
            getClient: getClient,//返回浏览器可视区域的位置
            getSubClient: getSubClient,// 返回待加载资源位置
            intens: bIntersect,// 判断两个矩形是否相交,返回一个布尔值
            hasClass: hasClass,//判断是否拥有指定样式
            addClass: addClass,//添加样式
            removeClass: removeClass,//移除样式
            updateCache: updateCache,//更新离线存储缓存
            clone: clone,//克隆对象，深度拷贝
            offset: offset,
            goUrl: goUrl,
            accAdd: accAdd,
            accSub: accSub,
            accMul: accMul,
            accDiv:accDiv,
            testName: ""
        };
    })();
    return tl;
})




